﻿using BuildPlannerLib.Enums;
using BuildPlannerLib.SimEvents;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BuildPlannerLib.PlayerActions
{
    // Class for all player-controlled actions
    public class PlayerAction
    {
        // Reference to the build class
        public Build Build;

        // ActionStatus enum property for the status of the action
        private ActionStatus status;
        public ActionStatus Status
        {
            get { return status; }
            set { status = value; }
        }

        // String property for the action description
        private string description;
        private string longDescription;
        public string Description
        {
            get { return description; }
            set { description = value; }
        }
        public string LongDescription
        {
            get { return longDescription; }
            set { longDescription = value; }
        }

        // String property for the error message
        private string error;
        public string Error
        {
            get { return error; }
            set { error = value; }
        }

        // Integer property for the supply when starting the action
        private int? startingSupplyCount;
        public int? StartingSupplyCount
        {
            get { return startingSupplyCount; }
            set { startingSupplyCount = value; }
        }

        // TimeSpan properties for the start and end time of the action
        private TimeSpan? startTime;
        private TimeSpan? endTime;
        public TimeSpan? StartTime
        {
            get { return startTime; }
            set { startTime = value; }
        }
        public TimeSpan? EndTime
        {
            get { return endTime; }
            set { endTime = value; }
        }

        // Integer properties for resource costs
        private int mineralCost;
        private int gasCost;
        private int supplyCost;
        private int timeDuration;
        public int MineralCost
        {
            get { return mineralCost; }
            set { mineralCost = value; }
        }
        public int GasCost
        {
            get { return gasCost; }
            set { gasCost = value; }
        }
        public int SupplyCost
        {
            get { return supplyCost; }
            set { supplyCost = value; }
        }
        public int TimeDuration
        {
            get { return timeDuration; }
            set { timeDuration = value; }
        }

        // Integer property for supply produced by the action
        private int supplyProduced;
        public int SupplyProduced
        {
            get { return supplyProduced; }
            set { supplyProduced = value; }
        }

        // Method for determining if the action can be completed ever at the current state
        public virtual bool RequirementsFilled()
        {
            Error = null;
            if (Build.Player.Minerals.Amount < MineralCost && Build.Map.MineralWorkers == 0)
            {
                Error = "Not enough minerals to complete this action.";
                return false;
            }
            if (Build.Player.Gas.Amount < GasCost && Build.Map.GasWorkers == 0)
            {
                Error = "Not enough gas to complete this action.";
                return false;
            }
            if (SupplyCost > 0 && (Build.Player.Supply.Amount + SupplyCost) > Build.Player.SupplyInProduction)
            {
                Error = "Not enough supply to complete this action.";
                return false;
            }
            return true;
        }

        // Method for determining if the action can be started now
        public virtual bool StartCheck()
        {
            if (Build.Player.Minerals.Amount < MineralCost)
                return false;
            if (Build.Player.Gas.Amount < GasCost)
                return false;
            if (SupplyCost > 0 && (Build.Player.Supply.Amount + SupplyCost) > Build.Player.SupplyMaximum.Amount)
                return false;
            return true;
        }

        // Method for starting the action
        public virtual void StartAction()
        {
            Status = ActionStatus.Started;
            Build.Player.Minerals.Change(-MineralCost);
            Build.Player.Gas.Change(-GasCost);
            Build.Player.Supply.Change(SupplyCost);

            Build.Player.SupplyInProduction += SupplyProduced;

            StartTime = Build.CurrentTime;
            EndTime = Build.CurrentTime + TimeConvert.ToTimeSpan(TimeDuration);

            int newTime = TimeConvert.ToInt(Build.CurrentTime) + TimeDuration;

            Build.EventList.Add(new FinishAction(this, newTime));
        }

        // Method for finishing the action
        public virtual void FinishAction()
        {
            Status = ActionStatus.Finished;
            Build.Player.SupplyMaximum.Change(SupplyProduced);
        }

        public void Reset()
        {
            Restart();
            StartTime = null;
            EndTime = null;
        }

        public void Restart()
        {
            Status = ActionStatus.NotStarted;
        }
    }
}
